/**
  ******************************************************************************
  * @file           : MMC5983.h
  * @author         : lengq
  * @brief          : None
  * @attention      : None
  * @date           : 2024/4/8
  ******************************************************************************
  */


#ifndef STRESS_DETECTION_MMC5983_H
#define STRESS_DETECTION_MMC5983_H

#include <stdint.h>
#include <stdbool.h>

#include "hdl_iic.h"
#include "hdl_gpio.h"
#include "hdl_clk.h"
#include "rtthread.h"

#include "utils.h"

#define    X                                                0
#define    Y                                                1
#define    Z                                                2
#define    XYZ                                              3

#define    MAX(A, B)                                (A > B) ? A : B;
#define    MIN(A, B)                                (A < B) ? A : B;

#define MMC5983_X_OUT_H                    0X00                //Device ID = 0x48
#define MMC5983_X_OUT_L                    0X01
#define MMC5983_Y_OUT_H                    0X02
#define MMC5983_Y_OUT_L                    0X03
#define MMC5983_Z_OUT_H                    0X04
#define MMC5983_Z_OUT_L                    0X05
#define MMC5983_XYZ_OUT                    0X06
#define MMC5983_TMP_OUT                    0X07
#define MMC5983_STATUS                    0X08
#define MMC5983_CTRL_0                    0X09
#define MMC5983_CTRL_1                    0X0A
#define MMC5983_CTRL_2                    0X0B
#define MMC5983_CTRL_3                    0X0C
#define MMC5983_ID                        0X2F

#define MMC5983_ADDRESS                    0x30
#define MMC5983_MAG_SCALE_16BIT        0.24414f
#define MMC5983_MAG_SCALE_18BIT        0.0625f

#define    MMC5983Delay(x)                    rt_thread_delay(x)


//typedef union {
//    struct {
//        uint8_t Meas_M_Done: 1;
//        uint8_t Meas_T_Done: 1;
//        uint8_t Res0: 2;
//        uint8_t OTP_Read_Done: 1;
//        uint8_t Res1: 3;
//    } Bit;
//    uint8_t Byte;
//} LeftMMC5983RegStatus;

typedef union {
    struct {
        uint8_t TM_M: 1;
        uint8_t TM_T: 1;
        uint8_t NT_meas_done_en: 1;
        uint8_t Set: 1;
        uint8_t Reset: 1;
        uint8_t Auto_SR_en: 1;
        uint8_t OTP_Read: 1;
        uint8_t Res0: 1;
    } Bit;
    uint8_t Byte;
} LeftMMC5983RegCtrl0;

typedef union {
    struct {
        uint8_t BW: 2;
        uint8_t X_Inhibit: 1;
        uint8_t YZ_Inhibit: 2;
        uint8_t Res0: 2;
        uint8_t SW_RST: 1;
    } Bit;
    uint8_t Byte;
} LeftMMC5983RegCtrl1;

typedef union {
    struct {
        uint8_t Cm_freq: 3;
        uint8_t Cmm_en: 1;
        uint8_t Prd_set: 3;
        uint8_t En_prd_set: 1;
    } Bit;
    uint8_t Byte;
} LeftMMC5983RegCtrl2;

typedef union {
    struct {
        uint8_t Res0: 1;
        uint8_t St_enp: 1;
        uint8_t St_enm: 1;
        uint8_t Res1: 3;
        uint8_t Spi_3w: 1;
        uint8_t Res2: 1;
    } Bit;
    uint8_t Byte;
} LeftMMC5983RegCtrl3;

typedef struct {

    __IO bool CalibStatus;            //true,正在校准，false，结束校准
    //参考值
    int32_t Mag_Reference_Val[XYZ];
    float Mag_Reference_K[XYZ];
    __IO float Magangle;
} MMC5983Var_t;

typedef enum
{
	MMC5983_IDLE,
	MMC5983_INIT,
	MMC5983_START,
	MMC5983_READ
}en_mmc5983_step_t;

typedef struct
{
	en_mmc5983_step_t step;
	
	float mag_x;
	float mag_y;
	float mag_z;
}stc_mmc5983_t;

typedef void (*mmc5983_callback_t)(stc_mmc5983_t pack_t);

//初始化
//int IIC_Init();
//static bool MMC5983_Read(uint32_t *buf);
//void MMC5983_thread_entry(void *parameter) ;
int mmc5983_init(void);

void MMC5983Calib(void) ;

void mmc5983_proc(void);

void mmc5983_start(void);

void mmc5983_callback_cbs_register(mmc5983_callback_t pCBS);

#endif //STRESS_DETECTION_MMC5983_H
